home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-11-18 | 2.7 KB | 73 lines | [TEXT/MPS ] |
- ======================================================
- Register Variables (for both Pascal and C programmers)
- ======================================================
-
- If you take a look at CTestSignal.c, the C version of the signal-testing MPW tool,
- you will note the following code in main():
-
- volatile long registerLong = 0;
-
- InitUFailure();
-
- if (code = CatchSignal()) {
- fprintf(stdout, "Signal caught in main; code = %d, (registerLong = %d)\n",
- code, registerLong);
- return 0;
- }
-
- registerLong = 0xffff;
-
- Signal(Value());
-
- The storage specifier volatile is used in the declaration of registerLong because
- of a potential problem with the value of register variables at the point of the
- CatchSignal(). This problem can occur when using longjmp() as well.
-
- What happens is that the compiler (being a clever little fellow) decides that a
- local scalar variable can be conveniently kept in a register. When the exception is
- raised, all non-scratch registers are restored to what they were before the
- CatchSignal() call. If registerLong is kept in D3, for instance, then it will have
- the value 0 instead of 0xffff while processing the exception.
-
- This can be a serious problem if the register variable holds something like a
- handle or pointer, since you are likely to want to dispose of the block that it
- references if an exception occurs.
-
- In C this potential difficulty can be avoided by declaring a variable volatile. The
- compiler will keep a local variable on the stack and not leave it in a register. So,
- the printf() displays the correct value of 65535. If you removed the volatile
- storage specifier, 0 would be value of registerLong when printf() was called. If there
- is any doubt about a variable in your C program, be volatile.
-
-
- In the Pascal PTestSignal.p tool in Main:
-
- registerLong: LONGINT;
-
- BEGIN
- {InitSignals has already been done}
- registerLong := 0;
-
- {catch Signals not otherwise caught by the program}
- code := CatchSignal;
- IF code <> 0 THEN BEGIN
- NumToString(code, aString);
- aString := Concat('Signal caught from main, code = ',aString,
- ', registerLong = ');
- DoCatchOutMain(aString, registerLong);
- END;
-
- registerLong := $FFFF;
-
- Signal(Value);
-
-
- The Pascal tool displays zero for the value of registerLong since the compiler keeps
- it in a D register. This means that you must be careful in your use of local variables
- when CatchSignal is involved. This is never a problem when using CatchFailures since
- the handler is a separate procedure and any locals of an enclosing procedure would be
- pulled off the stack by the handler.
-
- Apple is investigating ways to get the same kind of control in Pascal that the
- volatile storage specifier gives you in C. A future version of MPW Pascal will almost
- certainly have this capability.